<!--
 * @Author: Charsen
 * @Date: 2025-08-01 20:06
 * @LastEditors: wjc
 * @LastEditTime: 2025-10-28 14:34:14
 * @Description: 
-->
<template>
  <SearchHeader
    ref="searchHeaderRef"
    :search-former="searchFormer"
    @on-search="handleSearch"
    @on-reset="handleSearch"
  >
    <template #right-buttons>
      <slot name="right-top-button">
        <template v-if="showCreate && checkAction(actions.add || '')">
          <OptionAdd v-if="createSinglePage" :right="true" @on-add="goCreatePage" />
          <OptionAdd v-else :right="true" @on-add="showCreator" />
        </template>
      </slot>
      <slot name="right-top-button-append"></slot>
    </template>
  </SearchHeader>

  <slot name="statistic" v-bind="statistic"></slot>

  <TableWrapper
    ref="multipleTableRef"
    :left-span="leftSpan"
    :columns="columns"
    :list="list"
    :actions="actions"
    :loading="listLoading"
    :multi-select="multiSelect"
    :table-index="tableIndex"
    :page-former="pageFormer"
    @selection-change="handleSelectionChange"
    @on-show="showShower"
    @on-edit="showEditor"
    @on-edit-page="goEditPage"
    @on-del="handleDelete"
  >
    <template #left>
      <slot name="left"></slot>
    </template>

    <template #header-options>
      <div>
        <el-button
          v-if="multiSelect"
          v-action="actions.delBatch"
          :disabled="multipleSelection.length === 0"
          size="small"
          type="danger"
          @click="handleDeleteBatch"
        >
          删除
          <span class="i-custom-delete ml-6px wh-12px"></span>
        </el-button>

        <slot name="header-options"></slot>
      </div>

      <OptionTrashed
        v-if="showTrashed"
        v-action="actions.trashed"
        :return-by-query="returnByQuery"
        :trashed-route="getTrashedRoute()"
        :show-text="true"
      />
    </template>

    <template #pagination>
      <Pagination
        v-model:limit="pageFormer.page_limit"
        v-model:page="pageFormer.page"
        :total="pageFormer.total"
        @on-changed="fetchData"
      />
    </template>

    <!-- 传递所有插槽 -->
    <template v-for="(_, name) in $slots" #[name]="slotData">
      <slot :name="name" v-bind="slotData"></slot>
    </template>
  </TableWrapper>

  <Creator
    v-model:visible="createDialog.visible"
    :entity="entity"
    :form-size="formSize"
    :request-url="requestUrl"
    @on-stored="fetchData"
  />

  <Editor
    v-model:visible="editDialog.visible"
    :entity-id="editDialog.id"
    :entity="entity"
    :form-size="formSize"
    :request-url="requestUrl"
    @on-updated="handleUpdate"
  />

  <Shower
    v-model:visible="showDialog.visible"
    :entity-id="showDialog.id"
    :entity="entity"
    :form-size="formSize"
    :request-url="requestUrl"
  >
    <template v-for="(_, name) in $slots" #[name]="slotData">
      <slot :name="name" v-bind="slotData"></slot>
    </template>
  </Shower>
</template>

<script setup lang="ts">
  import { useCreator } from '#/hooks/useCreator'
  import { useDestroy } from '#/hooks/useDestroy'
  import { useEditor } from '#/hooks/useEditor'
  import { useLister } from '#/hooks/useLister'
  import { useShower } from '#/hooks/useShower'
  import checkAction from '#/utils/check-action'
  import { ElTable } from 'element-plus'

  defineOptions({
    name: 'ScaffoldEmbed',
  })

  const props = withDefaults(
    defineProps<{
      actions?: AclPermission
      createSinglePage?: boolean
      entity: string
      formSize?: string
      leftSpan?: number
      multiSelect?: boolean
      queryParams?: object
      requestUrl?: RequestUrl
      returnByQuery?: boolean
      showCreate?: boolean
      showTrashed?: boolean
      tableIndex?: boolean
      trashedRoute?: string
    }>(),
    {
      trashedRoute: '',
      actions: () => ({
        add: '',
        edit: '',
        del: '',
        delBatch: '',
        trashed: '',
      }),
      requestUrl: () => ({}),
      queryParams: () => ({}),
      multiSelect: true,
      showCreate: true,
      showTrashed: true,
      tableIndex: true,
      createSinglePage: false,
      returnByQuery: false,
      leftSpan: 0,
      formSize: 'small',
    }
  )

  // rightSpan 和 tableStyle 计算已移至 ScaffoldTableWrapper 组件

  const emits = defineEmits<{
    (e: 'on-fetched', res: object): void
    (e: 'on-deleted'): void
    (e: 'on-updated', res: object): void
  }>()
  const searchHeaderRef = ref()
  const multipleTableRef = ref<InstanceType<typeof ElTable>>()
  const multipleSelection = ref<any[]>([])
  const hookOptions = { entity: props.entity, formSize: props.formSize, url: props.requestUrl }

  const {
    list,
    listLoading,
    columns,
    statistic,
    searchFormer,
    pageFormer,
    handleSearchChange,
    handleSearchChangeWith,
    fetchData,
    fetchDataWith,
    goCreatePage,
    goEditPage,
    getTrashedRoute,
    updateListWithOne,
  } = useLister(hookOptions)

  const { createDialog, showCreator } = useCreator(hookOptions)
  const { editDialog, showEditor } = useEditor(hookOptions)
  const { showDialog, showShower } = useShower(hookOptions)
  const { handleDestroy, handleDestroyWith, handleDestroyBatch, handleDestroyBatchWith } =
    useDestroy({
      entity: props.entity,
      list,
    })

  const handleSelectionChange = (val: any[]) => (multipleSelection.value = val)
  const getSearchFormData = () => searchHeaderRef.value?.getSearchFormData()

  const handleDelete = (id: number | string): void => {
    props.requestUrl.destroy
      ? handleDestroyWith({ destroy: props.requestUrl.destroy, params: { ids: [id] } }, () =>
          emits('on-deleted')
        )
      : handleDestroy(id, () => emits('on-deleted'))
  }

  const handleDeleteBatch = (): void => {
    props.requestUrl.destroyBatch
      ? handleDestroyBatchWith(
          { destroyBatch: props.requestUrl.destroyBatch, params: { ids: getSelectIds() } },
          () => emits('on-deleted')
        )
      : handleDestroyBatch(getSelectIds(), () => emits('on-deleted'))
  }

  const handleUpdate = (data: object) => {
    updateListWithOne(data, editDialog.value.index)
    emits('on-updated', data)
  }

  const getSelectIds = (): string[] => {
    return multipleSelection.value.map((item: any) => item.id)
  }

  const handleSearch = (data: object) => {
    props.requestUrl.index
      ? handleSearchChangeWith(data, { index: props.requestUrl.index })
      : handleSearchChange(data)
  }

  const loadData = () => {
    const onFetched = (res: object) => {
      emits('on-fetched', res)
    }
    props.requestUrl.index
      ? fetchDataWith({ index: props.requestUrl.index, params: props.requestUrl.params }, onFetched)
      : fetchData(onFetched)
  }

  defineExpose({
    searchFormer,
    getSearchFormData,
    getSelectIds,
    fetchData: loadData,
  })

  onMounted(() => {
    loadData()
  })
</script>
